from odoo import fields, models, api
from odoo.exceptions import UserError, ValidationError

from ...functions.operation_control_fc import OperationControlFC

FULFILLMENT_TYPE = [('dropoff', '网点收件'), ('pickup', '上门取件'), ('collect', '网点取件'), ('delivery', '送货上门')]
EXPRESS_CATEGORY = [('native', '境内件'), ('internation', '国际件'), ('european', '联盟件')]


class RPCourierMailRoute(models.Model):
    _name = "rp.courier.mail.route"
    _description = '承运商邮路'
    _inherit = ['mail.thread', 'mail.activity.mixin']
    _sql_constraints = [('unique_name', 'UNIQUE(name,courier_id)', '同一个承运商，邮路名称必须唯一'),
                        ('unique_code', 'UNIQUE(code,courier_id)', '同一个承运商，邮路编码必须唯一')]

    courier_id = fields.Many2one(string='承运商', comodel_name='rp.courier', ondelete='cascade')

    name = fields.Char(string='名称', required=True, copy=False, index=True, tracking=True)
    code = fields.Char(string='编码', readonly=True, copy=False, index=True, tracking=True)

    available_volume_weight_ids = fields.Many2many(string='可用体积重', comodel_name='rp.volume.weight', related='courier_id.volume_weight_ids')
    volume_weight_id = fields.Many2one(string='体积重', comodel_name='rp.volume.weight', required=True, tracking=True)

    package_type_ids = fields.Many2many(string='包裹类型', comodel_name='rp.package.type', required=True, relation='rp_courier_mail_route_and_package_type_rel', column1='courier_mail_route_id', column2='package_type_id', tracking=True)
    aging_ids = fields.Many2many(string='时效', comodel_name='rp.aging', required=True, relation='rp_courier_mail_route_and_aging_rel', column1='courier_mail_route_id', column2='aging_id', tracking=True)

    ship_from_country_group_ids = fields.Many2many(string='启运地', comodel_name='res.country.group', required=True,
                                                   relation="rp_courier_route_from_country_group_rel", column1='courier_mail_route_id', column2='country_group_id', tracking=True)
    ship_to_country_group_ids = fields.Many2many(string='目的地', comodel_name='res.country.group', required=True,
                                                 relation='rp_courier_route_to_country_group_rel', column1='courier_mail_route_id', column2='country_group_id', tracking=True)

    # 头尾程
    operation_display = fields.Char(string='头尾程', default='-,-,-,-', compute='_depends_fulfill_operation', store=True, tracking=True)
    operation_dropoff = fields.Boolean(string='网点收件', default=False)
    operation_pickup = fields.Boolean(string='上门取件', default=False)
    operation_collect = fields.Boolean(string='网点取件', default=False)
    operation_delivery = fields.Boolean(string='送货上门', default=False)

    available_value_added_ids = fields.Many2many(string='可用增值服务', comodel_name='rp.value.added.service', related='courier_id.value_added_ids')
    value_added_ids = fields.Many2many(string='增值服务', comodel_name='rp.value.added.service',
                                       relation='rp_courier_mail_and_value_added_rel', column1='courier_mail_id', column2='value_added_id')

    # 其他配置
    express_category = fields.Selection(string='发件类型', selection=EXPRESS_CATEGORY, default=EXPRESS_CATEGORY[0][0], required=True)
    same_city_flag = fields.Boolean(string='同城', default=False)
    same_province_flag = fields.Boolean(string='同省', default=False)

    active_flag = fields.Boolean(string='有效', default=True, tracking=True)

    """
    Common
    """

    def _get_name(self):
        """ 重写display_name """
        name = self.name
        if self._context.get('show_display'):
            display_name = self.name if self.name else ''
            code = self.code if self.code else ''
            name = code + ' - ' + display_name
        return name

    def filling_from_to_groups(self):
        if self.same_city_flag and self.express_category == 'native' or self.same_province_flag and self.express_category == 'native':
            # 只有启用地，无目的地
            if len(self.ship_from_country_group_ids.ids) > 0 and len(self.ship_to_country_group_ids) == 0:
                self.write({'ship_to_country_group_ids': [(6, 0, self.ship_from_country_group_ids.ids)]})
            # 只有目的地，无启用地
            if len(self.ship_to_country_group_ids.ids) > 0 and len(self.ship_from_country_group_ids.ids) == 0:
                self.write({'ship_from_country_group_ids': [(6, 0, self.ship_to_country_group_ids.ids)]})
            # 启用地和目的地都有值
            if len(self.ship_from_country_group_ids.ids) > 0 and len(self.ship_to_country_group_ids.ids) > 0:
                self.write({'ship_to_country_group_ids': [(6, 0, self.ship_from_country_group_ids.ids)]})

    """
    原生函数
    """

    @api.model_create_multi
    def create(self, vals_list):
        for vals in vals_list:
            if not vals.get('courier_id', False):
                raise ValidationError("承运商必填")
        results = super(RPCourierMailRoute, self).create(vals_list)
        for result in results:
            prefix = self.env['rp.courier'].search([('id', '=', result.courier_id.id)]).code
            result.code = self.env['rp.sequence.code'].explore_sequence(model=self._name, prefix=prefix, key='RT', padding=3)
        return results

    def name_get(self):
        res = []
        for s in self:
            name = s._get_name()
            res.append((s.id, name))
        return res

    """
    constrains
    """

    @api.constrains('operation_pickup', 'operation_dropoff', 'operation_delivery', 'operation_collect')
    def _check_operation_info(self):
        for s in self:
            if s.courier_id:
                if all([s.courier_id.operation_pickup is False, s.operation_pickup is True]):
                    raise ValidationError('当前承运商不支持上门取件')
                if all([s.courier_id.operation_dropoff is False, s.operation_dropoff is True]):
                    raise ValidationError('当前承运商不支持网点收件')
                if all([s.courier_id.operation_delivery is False, s.operation_delivery is True]):
                    raise ValidationError('当前承运商不支持送货上门')
                if all([s.courier_id.operation_collect is False, s.operation_collect is True]):
                    raise ValidationError('当前承运商不支持网点取件')

    """
    Onchange
    """

    @api.onchange('courier_id')
    def _onchange_fulfill_courier_info(self):
        if self.courier_id:
            self.update({'operation_dropoff': self.courier_id.operation_dropoff,
                         'operation_pickup': self.courier_id.operation_pickup,
                         'operation_collect': self.courier_id.operation_collect,
                         'operation_delivery': self.courier_id.operation_delivery,
                         'value_added_ids': self.courier_id.value_added_ids})

    @api.onchange('same_city_flag', 'ship_to_country_group_ids', 'ship_from_country_group_ids')
    def _onchange_city_same_flag(self):
        if self.same_city_flag and self.express_category == 'native':
            self.update({'same_province_flag': False})
        self.filling_from_to_groups()

    @api.onchange('same_province_flag', 'ship_to_country_group_ids', 'ship_from_country_group_ids')
    def _onchange_province_same_flag(self):
        if self.same_province_flag and self.express_category == 'native':
            self.update({'same_city_flag': False})
        self.filling_from_to_groups()

    @api.onchange('express_category')
    def _onchange_express_category(self):
        if self.express_category in ['european', 'internation', 'false']:
            self.update({'same_city_flag': False, 'same_province_flag': False})

    """
    Depends
    """

    @api.depends('operation_pickup', 'operation_dropoff', 'operation_delivery', 'operation_collect')
    def _depends_fulfill_operation(self):
        for s in self:
            operation = OperationControlFC(self.env, s.operation_dropoff, s.operation_pickup, s.operation_collect, s.operation_delivery)

            s.write({'operation_display': operation.fulfill_display(),
                     'value_added_ids': [(6, 0, operation.update_value_add_list(s.value_added_ids.ids))]})

    @api.onchange('value_added_ids')
    def _onchange_value_added_ids(self):
        """ 头尾程的增值服务不允许删除 """
        if self.value_added_ids:
            operation = OperationControlFC(self.env, self.operation_dropoff, self.operation_pickup, self.operation_collect, self.operation_delivery)
            if not operation.monitor_value_add_list(self.value_added_ids.ids):
                raise UserError('增值服务中的头尾程不允许删除')
